package pt.compflow.client;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.restlet.Application;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.Restlet;
import org.restlet.routing.Router;

import pt.compflow.Context;
import pt.compflow.client.api.AuthResource;
import pt.compflow.client.api.JobFromTemplateResource;
import pt.compflow.client.api.JobResource;
import pt.compflow.client.api.PersonResource;
import pt.compflow.client.api.TaskInterfaceResource;
import pt.compflow.client.ui.InterfaceUIResource;
import pt.compflow.client.ui.JobCreateFromTemplateUIResource;
import pt.compflow.client.ui.JobCreateUIResource;
import pt.compflow.client.ui.JobUIResource;
import pt.compflow.client.ui.ProfileUIResource;
import pt.compflow.client.ui.RegisterUIResource;
import pt.compflow.client.ui.TemplateUIResource;
import pt.compflow.flowontology.model.FlowOntologyModel;
import pt.compflow.flowontology.model.PersonGroup;
import pt.compflow.flowontology.model.TaskInterface;
import pt.compflow.flowontology.model.WebTaskInterface;
import pt.compflow.storage.TripleStoreConnection;

public class EngineApplication extends Application {

	protected Context context;
	private List<EngineApplicationListener> listeners;

	public EngineApplication(Context context) {
		this.context = context;
		this.listeners = new ArrayList<EngineApplicationListener>();
	}

	@Override
	public Restlet createInboundRoot() {
		Router router = new Router(getContext());
		router.attachDefault(new ClientRestlet());
		
		TripleStoreConnection store = context.getStoreConnection();
		store.openStore();
		
		FlowOntologyModel model = store.connectModel();
		PersonGroup group = model.createPersonGroupWithURI(BaseResource.ADMIN_LOCAL_GROUP_URI);
		group.setLabel("Admin Local Group", null);
		
		PersonGroup localGroup = model.createPersonGroupWithURI(BaseResource.LOCAL_GROUP_URI);
		localGroup.setLabel("Normal Worker", null);
		
		store.closeStore();
		
		// CLIENT
		router.attach("/profile", ProfileUIResource.class);
		router.attach("/register", RegisterUIResource.class);
		router.attach("/job", JobUIResource.class);
		router.attach("/job/create", JobCreateUIResource.class);
		router.attach("/job/createFromTemplate", JobCreateFromTemplateUIResource.class);
		router.attach("/interface", InterfaceUIResource.class);
		
		router.attach("/_{template}", TemplateUIResource.class);
		router.attach("/", new Restlet() {
			@Override
			public void handle(Request req, Response res) {
				TripleStoreConnection store = context.getStoreConnection();
				store.openStore();
				
				FlowOntologyModel model = store.connectModel();
				Iterator<TaskInterface> it = model.listTaskInterfaces();
				boolean ok = false;
				if(it.hasNext()) {
					TaskInterface ti = it.next();
					if(ti.canAs(WebTaskInterface.class)) { ok = true; res.redirectSeeOther("/" + ti.getLocalName()); }
				} 
				
				if(!ok) res.redirectSeeOther("/job");
				
				store.closeStore();
			}
		});
		
		// API RESTFUL
		// PERSON (USER)
		router.attach("/api/person/{id}", PersonResource.class);
		router.attach("/api/person", PersonResource.class);
		router.attach("/api/auth", AuthResource.class);
		router.attach("/api/jobFromTemplate", JobFromTemplateResource.class);	//FIXME this should be the URI for this
		router.attach("/api/job", JobResource.class);
		router.attach("/api/job/{id}", JobResource.class);
		router.attach("/api/interface/task", TaskInterfaceResource.class);
		router.attach("/api/interface/task/{id}", TaskInterfaceResource.class);
				
		return router;
	}

	public Context getCompFlowContext() {
		return context;
	}

	public void setCompFlowContext(Context context) {
		this.context = context;
	}
	
	public void addEngineApplicationListener(EngineApplicationListener listener) {
		listeners.add(listener);
	}
	
	public void removeEngineApplicationListener(EngineApplicationListener listener) {
		listeners.remove(listener);
	}

	public List<EngineApplicationListener> getEngineApplicationListeners() {
		return listeners;
	}

}
